package com.fuershiye.woman.monitor.dao;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.springframework.transaction.annotation.Transactional;

import com.fuershiye.woman.monitor.beans.Pagination;
import com.fuershiye.woman.monitor.beans.QueryFiledEntry;

@Transactional
public interface HibernateDao {
  /**
   * 根据领域对象实例查询匹配的持久化对象集合，并返回封装后的分页对象。 例如：一个用户对象实例中指定了username属性，那么程序将会返回所有的匹配该username值的用户持久化对象。
   *
   * @param instance
   *          领域对象实例
   * @param startPage
   *          起始页
   * @param limit
   *          每页记录数量限制
   * @param orders
   *          用于指定排序规则的2维数据，例如：{{"username","asc"},{"createtime","desc"}}
   * @return 带有持久化对象集合的分页对象
   */
  Pagination queryByExample(Object instance, int startPage, int limit, String[][] orders);

  /**
   * 根据领域对象实例查询匹配的持久化对象集合，从数据表中的第一条记录开始。
   *
   * @param instance
   *          领域对象实例
   * @param max
   *          取出的最大记录数
   * @param orders
   *          用于指定排序规则的2维数据
   * @return 持久化对象集合
   */
  List<?> queryByExample(Object instance, int max, String[][] orders);

  /**
   * 根据领域对象实例查询匹配的持久化对象集合，从数据表中的第一条记录开始。
   *
   * @param instance
   *          领域对象实例
   * @param max
   *          取出的最大记录数
   * @return 持久化对象集合
   */
  List<?> queryByExample(Object instance, int max);

  /**
   * 根据领域对象实例查询匹配的持久化对象集合，取出全部。
   *
   * @param instance
   *          领域对象实例
   * @param orders
   *          用于指定排序规则的2维数据
   * @return 持久化对象集合
   */
  List<?> queryByExample(Object instance, String[][] orders);

  /**
   * 根据领域对象实例查询匹配的持久化对象集合，取出全部。
   *
   * @param instance
   *          领域对象实例
   * @return 持久化对象集合
   */
  List<?> queryByExample(Object instance);

  /**
   * 根据领域对象实例查询相似的持久化对象集合，类似数据库 like 查询。
   * 例如：一个用户对象实例中指定了email属性值为“%163.com”，那么程序将会返回所有邮件地址以163.com结尾的用户持久化对象。
   *
   * @param instance
   *          领域对象实例
   * @param like
   *          用于指定匹配属性的2维数组,集中值为sql like 查询的表达式，例如：{{"country","%中国%"},{"email","%163.com"}}
   * @param first
   *          起始记录位置
   * @param max
   *          取出的最大记录数量
   * @param orders
   *          用于指定排序规则的2维数据
   * @return 持久化对象集合
   */
  List<?> queryByDetailed(Object instance, int first, int max, String[][] orders);

  /**
   * 根据领域对象实例查询相似的、指定起始截止时间的条件的持久化对象集合，返回已分页对象。
   *
   * @param instance
   *          领域对象实例
   * @param like
   *          用于指定匹配属性的2维数组
   * @param startPage
   *          起始页
   * @param limit
   *          每页限制的记录数量
   * @param orders
   *          用于指定排序规则的2维数据
   * @return 带持久化对象集合的分页对象
   */
  Pagination queryByDetailedAsPagination(Object instance, int startPage, int limit, String[][] orders);

  /**
   * 根据领域对象实例查询相似的持久化对象集合,不排序
   *
   * @param instance
   *          领域对象实例
   * @param like
   *          用于指定匹配属性的2维数组
   * @param first
   *          起始记录位置
   * @param max
   *          取出的最大记录数量
   * @return 持久化对象集合
   */

  List<?> queryByDetailed(Object instance, int first, int max);

  /**
   * 根据领域对象实例查询相似的持久化对象集合,不排序
   *
   * @param instance
   *          领域对象实例
   * @param like
   *          用于指定匹配属性的2维数组
   * @param max
   *          取出的最大记录数量
   * @return 持久化对象集合
   */
  List<?> queryByDetailed(Object instance, int max);

  /**
   * 根据领域对象实例查询相似的持久化对象集合,不排序，取出全部
   *
   * @param instance
   *          领域对象实例
   * @param like
   *          用于指定匹配属性的2维数组
   * @return 持久化对象集合
   */
  List<?> queryByDetailed(Object instance);

  List<?> queryByDetailed(Object instance, String[][] orders);

  /**
   * 根据属性拓展对象和条件对象集合组查询
   *
   * @param aeo
   *          属性拓展对象
   * @param queryfileds
   *          查询条件集合
   * @return 持久化对象集合
   */
  List<?> queryByDetailedAndEntrys(Object instance, List<QueryFiledEntry> queryfiledentrys);

  List<?> queryByDetailedAndEntrys(Object instance, List<QueryFiledEntry> queryfiledentrys,
          int max, String[][] orders);

  List<?> queryByDetailedAndEntrys(Object instance, List<QueryFiledEntry> queryfiledentrys,
          int first, int max, String[][] orders);

  Pagination queryByDetailedAndEntrysAsPagination(Object instance,
          List<QueryFiledEntry> queryfiledentrys, int startPage, int limit, String[][] orders);

  /**
   * 获得一个Hibernate 查询器
   *
   * @param hql
   *          查询语句
   * @return Hibernate 查询器
   */
  Query getQuery(String hql);

  /**
   * 根据领域对象类型和唯一标识符，查询持久化对象
   *
   * @param entryClass
   *          对象类型
   * @param id
   *          唯一标识符
   * @return 持久化对象
   */
  SQLQuery getSqlQuery(String sql);

  <T> T getById(Class<T> entryClass, Object id);

  <T> List<T> getAll(Class<T> entryClass);

  /**
   * 根据领域对象类型和唯一标识符，查询持久化对象
   *
   * @param entryClass
   *          对象类型
   * @param id
   *          唯一标识符
   * @return 持久化对象，如结果为空，则抛出异常
   */
  <T> T loadById(Class<T> entryClass, Object id);

  /**
   * 保存一个领域对象
   *
   * @param persistentInstance
   *          对象示例
   */
  void save(Object persistentInstance);

  /**
   * 保存一个领域对象但是不提交事务
   *
   * @param persistentInstance
   */

  void saveNotCommit(Object persistentInstance);

  /**
   * 提交事务
   *
   * @param persistentInstance
   */
  void commit();

  /**
   * 删除一个领域对象，对象必须处于持久化状态。
   *
   * @param persistentInstance
   *          持久化对象
   */
  void delete(Object persistentInstance);

  /**
   * 合并session中的拥有同一个唯一标识符的持久化对象，并调用saveOrUpdate方法保存合并后的持久化对象
   *
   * @param object
   */
  Object merge(Object object);

  /**
   * 刷新hinerbate session
   */
  void flush();

  /**
   * 关闭hinerbate session，此方法将调用flush()
   */
  void close();

  /**
   * 清空hinerbate session中的所有已缓存的持久化对象
   */
  void clear();

  /**
   * 获取一个分页
   *
   * @param query
   *          主查询器，用于查询符合条件的持久化对象集合。
   * @param countQuery
   *          统计查询器，用于查询符合条件的持久化对象的总数。
   * @param startPage
   *          起始页
   * @param limit
   *          每页最大记录数量限制
   * @return 分页对象
   */
  Pagination getPagination(Query query, Query countQuery, int startPage, int limit);

  List<?> queryAllOrder();

  void updateMessage(Object persistentInstance);

  /**
   * 清空hinerbate session中的参数指定的持久化对象
   */
  void evict(Object obj);

  List<?> queryByDetailedGroup(Object instance, String selectSub, String[] groupField,
          String[][] orders);

  List<?> queryByDetailedGroup(Object instance, String selectSub, String[] groupField,
          String[][] orders, Integer limit);

  Session getCurrentSession();
}

